use crate::types::Type;
use std::collections::HashMap;
use std::ops::Index;

pub type NativeMethod = fn(Vec<Type>) -> Option<Type>;

pub struct NativeLibrary {
    name_to_method: HashMap<&'static str, NativeMethod>,
}

impl Index<&str> for NativeLibrary {
    type Output = NativeMethod;

    fn index(&self, idx: &str) -> &Self::Output {
        &self.name_to_method[idx]
    }
}

impl Default for NativeLibrary {
    fn default() -> Self {
        NativeLibrary {
            name_to_method: [
                (
                    "ru/khlevnov/PrintStream.print:(I)V",
                    PrintStream::print as NativeMethod,
                ),
                ("ru/khlevnov/PrintStream.println:(I)V", PrintStream::println),
            ]
            .into(),
        }
    }
}

struct PrintStream;

impl PrintStream {
    fn print(args: Vec<Type>) -> Option<Type> {
        print!("{}", args[0]);
        None
    }

    fn println(args: Vec<Type>) -> Option<Type> {
        println!("{}", args[0]);
        None
    }
}
